#include "StdAfx.h"
#include <boost/lexical_cast.hpp>
#include "MenuDialog.h"
#include "MainFrame.h"
#include "Renderer.h"
#include "EasyBMP/EasyBMP.h"

CMenuDialog::CMenuDialog(CMainFrame* pMainFrame)
: m_pMainFrame(pMainFrame)
{
}


CMenuDialog::~CMenuDialog(void)
{
}

void CMenuDialog::Load(const string& strFileName)
{
	CEGUI::Window* pRoot = CEGUI::WindowManager::getSingleton().loadWindowLayout(strFileName);
	if (pRoot == NULL)
		return;

	CEGUI::System::getSingleton().setGUISheet(pRoot);

	CEGUI::Window* pFrame = pRoot->getChild("Root/MenuFrame");

	m_pInputXMLText = static_cast<CEGUI::Editbox*>(pFrame->getChild("Root/MenuFrame/InputXMLEdit"));
	m_pInputBMPText = static_cast<CEGUI::Editbox*>(pFrame->getChild("Root/MenuFrame/InputBMPEdit"));
	m_pInputXMLButton = static_cast<CEGUI::PushButton*>(pFrame->getChild("Root/MenuFrame/InputXMLButton"));
	m_pInputBMPButton = static_cast<CEGUI::PushButton*>(pFrame->getChild("Root/MenuFrame/InputBMPButton"));

	m_pBasicRadioButton = static_cast<CEGUI::RadioButton*>(pFrame->getChild("Root/MenuFrame/Sampling/Basic"));
	m_pJitteredRadioButton = static_cast<CEGUI::RadioButton*>(pFrame->getChild("Root/MenuFrame/Sampling/Jittered"));
	m_pAdaptiveRadioButton = static_cast<CEGUI::RadioButton*>(pFrame->getChild("Root/MenuFrame/Sampling/Adaptive"));

	m_pRefractionCheckButton = static_cast<CEGUI::Checkbox*>(pFrame->getChild("Root/MenuFrame/Refraction"));
	m_pReflectionCheckButton = static_cast<CEGUI::Checkbox*>(pFrame->getChild("Root/MenuFrame/Reflection"));
	m_pMotionBlurCheckButton = static_cast<CEGUI::Checkbox*>(pFrame->getChild("Root/MenuFrame/MotionBlur"));
	m_pDepthOfFieldCheckButton = static_cast<CEGUI::Checkbox*>(pFrame->getChild("Root/MenuFrame/DepthOfField"));
	m_pKDTreeCheckButton = static_cast<CEGUI::Checkbox*>(pFrame->getChild("Root/MenuFrame/KDTree"));

	m_pMotionBlurEdit = static_cast<CEGUI::Editbox*>(pFrame->getChild("Root/MenuFrame/MotionBlurEdit"));
	m_pDepthOfFieldEdit = static_cast<CEGUI::Editbox*>(pFrame->getChild("Root/MenuFrame/DepthOfFieldEdit"));

	m_pBGColorR = static_cast<CEGUI::Editbox*>(pFrame->getChild("Root/MenuFrame/BGColorRValue"));
	m_pBGColorG = static_cast<CEGUI::Editbox*>(pFrame->getChild("Root/MenuFrame/BGColorGValue"));
	m_pBGColorB = static_cast<CEGUI::Editbox*>(pFrame->getChild("Root/MenuFrame/BGColorBValue"));

	m_pRenderButton = static_cast<CEGUI::PushButton*>(pFrame->getChild("Root/MenuFrame/RenderButton"));

	m_pRenderButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&CMenuDialog::OnRenderButtonClicked, this));

	m_pInputXMLButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&CMenuDialog::OnXMLButtonClicked, this));
	m_pInputBMPButton->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&CMenuDialog::OnBMPButtonClicked, this));

	m_pBasicRadioButton->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnSamplingChanged, this));
	m_pJitteredRadioButton->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnSamplingChanged, this));
	m_pJitteredRadioButton->subscribeEvent(CEGUI::RadioButton::EventSelectStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnSamplingChanged, this));

	m_pRefractionCheckButton->subscribeEvent(CEGUI::Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnVisualEffectChanged, this));
	m_pReflectionCheckButton->subscribeEvent(CEGUI::Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnVisualEffectChanged, this));
	m_pMotionBlurCheckButton->subscribeEvent(CEGUI::Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnVisualEffectChanged, this));
	m_pDepthOfFieldCheckButton->subscribeEvent(CEGUI::Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnVisualEffectChanged, this));
	m_pKDTreeCheckButton->subscribeEvent(CEGUI::Checkbox::EventCheckStateChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnKDTreeChanged, this));

	m_pBGColorR->subscribeEvent(CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnBGColorChanged, this));
	m_pBGColorG->subscribeEvent(CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnBGColorChanged, this));
	m_pBGColorB->subscribeEvent(CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnBGColorChanged, this));

	m_pMotionBlurEdit->subscribeEvent(CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnVisualEffectChanged, this));
	m_pDepthOfFieldEdit->subscribeEvent(CEGUI::Editbox::EventTextChanged, CEGUI::Event::Subscriber(&CMenuDialog::OnVisualEffectChanged, this));

	m_pBasicRadioButton->setSelected(false);
	m_pJitteredRadioButton->setSelected(false);
	m_pAdaptiveRadioButton->setSelected(true);

	m_pRefractionCheckButton->setSelected(true);
	m_pReflectionCheckButton->setSelected(true);

	m_pMotionBlurCheckButton->setSelected(false);
	m_pDepthOfFieldCheckButton->setSelected(false);
	m_pKDTreeCheckButton->setSelected(true);
}

bool CMenuDialog::OnXMLButtonClicked(const CEGUI::EventArgs& e)
{
	const CEGUI::String strXMLFileName = m_pInputXMLText->getText();
	m_pMainFrame->ReloadScene(strXMLFileName.c_str());
	return true;
}

bool CMenuDialog::OnBMPButtonClicked(const CEGUI::EventArgs& e)
{
	if (m_pMainFrame->GetRenderer() == NULL)
	{
		return true;
	}

	const unsigned char* pPixel = m_pMainFrame->GetRenderer()->GetPixels();

	BMP output;
	output.SetSize(WINDOW_WIDTH, WINDOW_HEIGHT);
	output.SetBitDepth(24);
	
	for (int y = 0; y < WINDOW_HEIGHT; ++y)
	{
		for (int x = 0; x < WINDOW_WIDTH; ++x)
		{
			RGBApixel newPixel;
			newPixel.Red = *(pPixel++);
			newPixel.Green = *(pPixel++);
			newPixel.Blue = *(pPixel++);
			output.SetPixel(x, WINDOW_HEIGHT - y - 1, newPixel);
		}
	}

	const CEGUI::String strBMPFileName = m_pInputBMPText->getText();
	output.WriteToFile(strBMPFileName.c_str());

	return true;
}

bool CMenuDialog::OnSamplingChanged(const CEGUI::EventArgs& e)
{
	if (m_pMainFrame->GetRenderer() == NULL)
	{
		return true;
	}

	if (m_pBasicRadioButton->isSelected())
	{
		m_pMainFrame->GetRenderer()->SetSamplingMode(CRenderer::SM_BASIC);
	}
	else if(m_pJitteredRadioButton->isSelected())
	{
		m_pMainFrame->GetRenderer()->SetSamplingMode(CRenderer::SM_JITTERED);
	}
	else
	{
		m_pMainFrame->GetRenderer()->SetSamplingMode(CRenderer::SM_ADAPTIVE);
	}
	return true;
}

bool CMenuDialog::OnVisualEffectChanged(const CEGUI::EventArgs& e)
{
	if (m_pMainFrame->GetRenderer() == NULL)
	{
		return true;
	}

	m_pMainFrame->GetRenderer()->SetRefractionEnabled(m_pRefractionCheckButton->isSelected());
	m_pMainFrame->GetRenderer()->SetReflectionEnabled(m_pReflectionCheckButton->isSelected());

	m_pMainFrame->GetRenderer()->SetMotionBlurEnabled(m_pMotionBlurCheckButton->isSelected());
	m_pMainFrame->GetRenderer()->SetDepthOfFieldEnabled(m_pDepthOfFieldCheckButton->isSelected());

	const CEGUI::String& motionBlur = m_pMotionBlurEdit->getText();
	const CEGUI::String& depthOfField = m_pDepthOfFieldEdit->getText();

	try
	{
		m_pMainFrame->GetRenderer()->SetMotionBlurValue(boost::lexical_cast<DATA_TYPE>(motionBlur));
		m_pMainFrame->GetRenderer()->SetDepthOfFieldValue(boost::lexical_cast<DATA_TYPE>(depthOfField));
	}
	catch (boost::bad_lexical_cast &)
	{
		
	}

	return true;
}

bool CMenuDialog::OnKDTreeChanged(const CEGUI::EventArgs& e)
{
	if (m_pMainFrame->GetRenderer() == NULL)
	{
		return true;
	}

	m_pMainFrame->GetRenderer()->SetKDTreeEnabled(m_pKDTreeCheckButton->isSelected());

	return true;
}

bool CMenuDialog::OnBGColorChanged(const CEGUI::EventArgs& e)
{
	if (m_pMainFrame->GetRenderer() == NULL)
	{
		return true;
	}

	const CEGUI::String& r = m_pBGColorR->getText();
	const CEGUI::String& g = m_pBGColorG->getText();
	const CEGUI::String& b = m_pBGColorB->getText();

	try
	{
		m_pMainFrame->GetRenderer()->SetBGColor(CColor4(boost::lexical_cast<DATA_TYPE>(r.c_str())/255,
			boost::lexical_cast<DATA_TYPE>(g.c_str())/255, 
			boost::lexical_cast<DATA_TYPE>(b.c_str())/255, 1.f));
	}
	catch(boost::bad_lexical_cast &)
	{

	}

	return true;
}

bool CMenuDialog::OnRenderButtonClicked(const CEGUI::EventArgs& e)
{
	if (m_pMainFrame->GetRenderer() == NULL)
	{
		return true;
	}

	m_pMainFrame->GetRenderer()->DoRender();

	return true;
}